<template>
  <div>
    <el-card>
      <div>当班次节拍分析</div>
      <div ref="chart" :style="{ width: '1300px', height: '400px' }"></div>
      <div style="margin-top: 20px" class="grid-buttons">
        <button @click="fetchAndDisplayData('auto')" class="button">自动站</button>
        <button @click="fetchAndDisplayData('manual')" class="button">手动站</button>
        <button @click="fetchAndDisplayData('all')" class="button">整线</button>
      </div>
      <el-button type="primary" @click="exportToExcel">导出到Excel</el-button>
    </el-card>
  </div>
  <div>
    <el-card>
      <el-table :data="tableData" border style="width: 80%">
        <el-table-column prop="total_stations" label="总工位数" width="220"></el-table-column>
        <el-table-column prop="overstations" label="超上限工位数" width="220"></el-table-column>
        <el-table-column prop="lessstations" label="超下限工位数" width="200"></el-table-column>
        <el-table-column prop="compliant_stations" label="工位符合数" width="200"></el-table-column>
        <el-table-column prop="compliance_rate" label="工位符合率" width="200"></el-table-column>
      </el-table>
    </el-card>

    <!-- 控制显示隐藏的按钮 -->
    <button @click="toggleAdjustments" class="white-button">{{ showAdjustments ? '' : '' }}</button>

    <!-- 根据showAdjustments变量控制显示或隐藏 -->
    <el-card v-if="showAdjustments">
      <div class="reset-adjustments">
        <button @click="resetAllAdjustments" class="button">补偿刷新</button>
      </div>
      <el-table :data="filteredMockdata" style="width: 100%; margin-top: 20px">
        <el-table-column prop="station" label="工位" />
        <el-table-column prop="cycletime" label="当前节拍" />
        <el-table-column label="节拍补偿">
          <template #default="{ row }">
            <el-input v-model.number="row.adjustmentValue" placeholder="输入补偿值" style="width: 100px" />
            <el-button @click="adjustCycleTimeForStation(row)" size="small">应用</el-button>
          </template>
        </el-table-column>
        <el-table-column prop="targetCycle" label="目标节拍" />
        <el-table-column prop="totalAdjustment" label="累计补偿" />
      </el-table>
    </el-card>
  </div>
</template>

<script>
import * as echarts from 'echarts';
import axios from 'axios'; 
import {markRaw, ref} from "vue";
import * as XLSX from 'xlsx';
import { useLocalStorage } from '@vueuse/core'; 

export default {
  name: '',
  data() {
    return {
      showAdjustments: false, 
      chart: null,
      mockdata: [],
      targetCycleData: [],
      tableData: [
        { total_stations: 0, compliant_stations: 0,overstations: 0,lessstations: 0, compliance_rate: '-' },
      ],
      targetCycleDataMapped:[],
      stationsToExclude: ['1210S1','3020M','2260M','2170M','1355B','1110M','1295B','2410M','2140M','1350A-2','2090M','3030S1','1210S2','2370M','1420M','2440M', '1006R', '1008B', '1035B', '1040M', '1095B', '1096R', '1115B', '1126R', '1150M', '1165B', '1195B', '1196R', '1445R', '1235B', '1245B', '1265R', '1070M', '1075B',
        '1266R', '1315B', '1366R', '1368B', '1090A', '1416R', '1430M-2', '2040M', '2055B', '2115B', '2145R', '2006R', '2356R', '3105R', '2120M', '2135B', '2155B', '2196R', '2225R', '1405B', '2236R', '2370A', '2420M', '2430M', '2450M', '2476R', '2505B',
        '1140M','2185B','2475A','2320M','3110A','3040S','3030S2','2255M','3120M','1270M','2080M','1160A','1055M','2130A-1'
      ], 
      adjustmentValues: {},
      adjustmentHistory: {},
      originalCycleTimes: {},
      totalAdjustments: {},
      selectedType: 'all',
    };
  },
  computed: {
    filteredMockdata() {
      const uniqueStations = this.mockdata.filter(station => !this.stationsToExclude.includes(station.station));
      const stationMap = new Map();
      uniqueStations.forEach(station => {
        if (!stationMap.has(station.station)) {
          stationMap.set(station.station, station);
        }
      });
      const uniqueStationsArray = Array.from(stationMap.values());
      this.updateAverageCycle(uniqueStationsArray);
      uniqueStationsArray.forEach(station => {
        station.status = station.isOverCycle ? '超上限' : station.islessCycle ? '超下限' : '合格';
      });
      uniqueStationsArray.forEach(station => {
        const adjustment = this.adjustmentHistory[station.station];
        const totalAdjustment = this.totalAdjustments[station.station] || 0;
        if (adjustment !== undefined) {
          station.cycletime = this.originalCycleTimes[station.station] + adjustment;
          station.totalAdjustment = totalAdjustment;
        }
      });

      return uniqueStationsArray;
    },
  },
  async mounted() {
    try {
      await this.fetchDataFromApi();
      await this.fetchEquipmentTargetTimeData();
      console.log("接口返回的完整数据:", this.mockdata);
      console.log("目标节拍数据:", this.targetCycleData);
      console.log("节拍数据:", this.targetCycleDataMapped);
      this.initChart();
      this.loadAdjustmentsFromLocalStorage();
    } catch (error) {
      console.error('Error fetching data:', error);
    }
  },
  methods: {
    async fetchEquipmentTargetTimeData() {
    try {
      const response = await axios.get('http://10.64.35.32:8000/manufacture_analysis/get_ms_cycle_data/?page_size=1000');
      const equipmentTargetTimeData = response.data;
      const targetTimeMap = new Map();
      equipmentTargetTimeData.forEach(station => {
        targetTimeMap.set(station.station, station.equipment_target_time);
      });
      this.filteredMockdata.forEach(station => {
        if (targetTimeMap.has(station.station)) {
          const targetTime = targetTimeMap.get(station.station);
          station.totalAdjustment += targetTime; 
        }
      });
      console.log('ttt',this.filteredMockdata)
      this.saveAdjustmentsToLocalStorage();
      this.initChart();
    } catch (error) {
      console.error("Error fetching equipment target time data:", error);
    }
  },
    updateAverageCycle(data) {
      const sumCycleTimes = data.reduce((acc, station) => acc + station.cycletime, 0);
      const averageCycleTime = sumCycleTimes / data.length;
      this.targetCycleData.average = averageCycleTime;
    },
    toggleAdjustments() {
      this.showAdjustments = !this.showAdjustments;
    },
    adjustCycleTimeForStation(station) {
      if (station.adjustmentValue !== undefined && station.adjustmentValue !== 0) {
        const adjustment = station.adjustmentValue;
        station.cycletime += adjustment;
        station.totalAdjustment = (station.totalAdjustment || 0) + adjustment;
        station.adjustmentValue = 0; 
        this.adjustmentHistory[station.station] = adjustment;
        this.totalAdjustments[station.station] = station.totalAdjustment;
        this.originalCycleTimes[station.station] = station.cycletime - adjustment;
        this.updateAverageCycle(this.filteredMockdata);
        this.saveAdjustmentsToLocalStorage();
        this.initChart(); 
        this.fetchAndDisplayData();
      }
    },
    resetAllAdjustments() {
      Object.keys(this.adjustmentHistory).forEach(station => {
        const stationObj = this.filteredMockdata.find(s => s.station === station);
        if (stationObj) {
          stationObj.cycletime = this.originalCycleTimes[station]; 
          stationObj.totalAdjustment = 0; 
          stationObj.adjustmentValue = 0;
          this.fetchDataFromApi();
        }
      });

      this.adjustmentHistory = {}; 
      this.totalAdjustments = {}; 
      this.updateAverageCycle(this.filteredMockdata); 
      this.saveAdjustmentsToLocalStorage(); 
      this.resetChart(); 
    },
    loadAdjustmentsFromLocalStorage() {
      const storedAdjustments = JSON.parse(localStorage.getItem('adjustmentHistory'));
      const storedTotalAdjustments = JSON.parse(localStorage.getItem('totalAdjustments'));
      const storedOriginalCycleTimes = JSON.parse(localStorage.getItem('originalCycleTimes'));

      if (storedAdjustments && storedTotalAdjustments && storedOriginalCycleTimes) {
        this.adjustmentHistory = storedAdjustments;
        this.totalAdjustments = storedTotalAdjustments;
        this.originalCycleTimes = storedOriginalCycleTimes;

        this.applyAdjustmentsAndInitChart();
      }
    },
    applyAdjustmentsAndInitChart() {
      Object.keys(this.adjustmentHistory).forEach(station => {
        const stationObj = this.filteredMockdata.find(s => s.station === station);
        if (stationObj) {
          stationObj.cycletime = this.originalCycleTimes[station] + this.adjustmentHistory[station];
          stationObj.totalAdjustment = this.totalAdjustments[station];
        }
      });
      this.updateAverageCycle(this.filteredMockdata);

      this.initChart();
    },
    saveAdjustmentsToLocalStorage() {
      localStorage.setItem('adjustmentHistory', JSON.stringify(this.adjustmentHistory));
      localStorage.setItem('totalAdjustments', JSON.stringify(this.totalAdjustments));
      localStorage.setItem('originalCycleTimes', JSON.stringify(this.originalCycleTimes));
    },
    exportToExcel() {
  const now = new Date();
  const year = now.getFullYear();
  const month = ('0' + (now.getMonth() + 1)).slice(-2); 
  const day = ('0' + now.getDate()).slice(-2);
  const hours = ('0' + now.getHours()).slice(-2);
  const minutes = ('0' + now.getMinutes()).slice(-2);
  const seconds = ('0' + now.getSeconds()).slice(-2);
  
  const fileName = `${year}-${month}-${day}_${hours}-${minutes}-${seconds}_整线节拍统计.xlsx`;
  
  const workbook = XLSX.utils.book_new();
  const ws = XLSX.utils.json_to_sheet(this.mockdata);
  XLSX.utils.book_append_sheet(workbook, ws, 'Sheet1');

  const fileData = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
  const blob = new Blob([fileData], { type: 'application/octet-stream' });
  const url = window.URL.createObjectURL(blob);

  const a = document.createElement('a');
  a.href = url;
  a.download = fileName;
  a.click();

  window.URL.revokeObjectURL(url);
},
    async fetchAutoStationData() {
  try {
    const response = await axios.get('http://10.64.35.32:8000/as_manage_analysis/get_fine_as_data/?page=1&page_size=100&station_type=A');
    this.mockdata = response.data;

    const responseCycle = await axios.get('http://10.64.35.32:8000/as_manage_analysis/get_as_cycle_data/?page=1&page_size=1');
    this.targetCycleData = responseCycle.data[0].cycle;

    this.targetCycleDataMapped = Object.entries(this.targetCycleData).map(([station, cycle]) => ({
    name: station, 
    value: [station, cycle], 
    }));
       console.log("自动:", this.targetCycleData);
        this.mockdata.forEach(station => {
      const targetCycle = this.targetCycleData[station.station];
      if (targetCycle !== undefined) {
        station.targetCycle = targetCycle; 
      }
    });

    // 重置图表数据
    this.initChart();
    this.fetchAndDisplayData();
  } catch (error) {
    console.error("Error fetching auto station data:", error);
  }
},

  async fetchManualStationData() {
      try {
        const response = await axios.get('http://10.64.35.32:8000/as_manage_analysis/get_fine_as_data/?page=1&page_size=100&station_type=M');
        this.mockdata = response.data;
        const response1 = await axios.get('http://10.64.35.32:8000/as_manage_analysis/get_as_cycle_data/?page=1&page_size=1');
        this.targetCycleData = response1.data[0].cycle;
        this.targetCycleDataMapped = Object.entries(this.targetCycleData).map(([station, cycle]) => ({
    name: station, 
    value: [station, cycle], 
  }));

        this.mockdata.forEach(station => {
      const targetCycle = this.targetCycleData[station.station];
      if (targetCycle !== undefined) {
        station.targetCycle = targetCycle; 
      }
    });

    this.initChart();
    this.fetchAndDisplayData();
      } catch (error) {
        console.error("Error fetching data:", error);
      }
    },
  
    
    fetchAndDisplayData(stationType) {
    let filteredData = this.mockdata; 
    if (stationType === 'auto') {
      this.fetchAutoStationData();
    } else if (stationType === 'all') {
      this.fetchDataFromApi();
    }else if (stationType === 'manual') {
      this.fetchManualStationData();
    } else {
      console.warn('Invalid station type specified.');
    }

    filteredData = filteredData.filter(item => !this.stationsToExclude.includes(item.station));

    // 计算总工位数和橙色工位数
    let totalStations = 0;
    let overStations = 0;
    let lessStations = 0;

    filteredData.forEach(station => {
      totalStations++;
      if (station.cycletime > this.targetCycleData[station.station]*1.05) {
        overStations++;
      }else if(station.cycletime < this.targetCycleData[station.station]*0.95) {
        lessStations++;
      }
    });

    const stationComplianceRate = totalStations > 0 ? ((totalStations - overStations - lessStations) / totalStations) * 100 : 0;

    this.tableData = [
      { total_stations: totalStations, compliant_stations: totalStations - overStations - lessStations,overstations: overStations,lessstations: lessStations, compliance_rate: `${stationComplianceRate.toFixed(2)}%` },
    ];

    this.initChart();
    console.log('总工位',totalStations)
    console.log('符合率',`${stationComplianceRate.toFixed(2)}%`)
  },
    async fetchDataFromApi() {
      try {
        const response = await axios.get('http://10.64.35.32:8000/as_manage_analysis/get_fine_as_data/?page=1&page_size=150');
        this.mockdata = response.data;
        const response1 = await axios.get('http://10.64.35.32:8000/as_manage_analysis/get_as_cycle_data/?page=1&page_size=1');
        this.targetCycleData = response1.data[0].cycle;
        this.targetCycleDataMapped = Object.entries(this.targetCycleData).map(([station, cycle]) => ({
    name: station, 
    value: [station, cycle], 
  }));

        this.mockdata.forEach(station => {
      const targetCycle = this.targetCycleData[station.station];
      if (targetCycle !== undefined) {
        station.targetCycle = targetCycle; 
      }
    });
      
    this.initChart();
    this.fetchAndDisplayData();
      } catch (error) {
        console.error("Error fetching data:", error);
      }
    },
    initChart() {
      if (this.chart) {
        this.chart.dispose();
      }
      this.chart = markRaw(echarts.init(this.$refs.chart));
      const filteredData = this.mockdata.filter(item => !this.stationsToExclude.includes(item.station));
      filteredData.forEach(station => {
    station.isOverCycle = station.cycletime > this.targetCycleData[station.station]*1.05;
    station.islessCycle = station.cycletime < this.targetCycleData[station.station]*0.95;
  });
      const targetCycleForStations = filteredData.reduce((acc, station) => {
    const targetCycle = this.targetCycleData[station.station];
    if (targetCycle !== undefined) {
      acc.push({ name: station.station, value: targetCycle });
    }
    return acc;
      }, []);

      const upperLimit = targetCycleForStations.map(item => item.value * 1.05);
      const lowerLimit = targetCycleForStations.map(item => item.value * 0.95);
      console.log('上限',upperLimit)
      console.log(targetCycleForStations.map(item => item.value * 1))
      console.log(this.mockdata.map(item => parseFloat(item.ftq)*100))
      const option = {
        title: {
        text: '',
          left: 'center',
        top:20,
        textStyle: {
        fontSize: 20,
        fontWeight: 'bold',
      },
    },
        tooltip: {
  trigger: 'axis',
  axisPointer: {
    type: 'shadow'
  },
  formatter: function (params) {
  
    const dataIndex = params[0].dataIndex;
    
    const detailData = filteredData[dataIndex];

    const targetCycle = detailData.targetCycle || 'N/A';
    
   
    const totalProduced = detailData.count_good + detailData.count_reject;
    
    const overcycle_ratio = (detailData.overcycle / totalProduced) * 100;
 
    let tooltipContent = `<strong>${detailData.station}</strong><br>`;
    tooltipContent += `平均节拍: ${detailData.cycletime}s<br>`;
    tooltipContent += `目标节拍: ${targetCycle}s<br>`;
    tooltipContent += `FTQ: ${(detailData.ftq * 100).toFixed(2)}%<br>`;
    tooltipContent += `合格数: ${detailData.count_good}<br>`;
    tooltipContent += `不合格数: ${detailData.count_reject}<br>`;
    tooltipContent += `最大节拍: ${detailData.maxcycle}s<br>`;
    tooltipContent += `最小节拍: ${detailData.mincycle}s<br>`;
    tooltipContent += `超节拍数量: ${detailData.overcycle}<br>`;
    tooltipContent += `超+3%CT数量:${detailData.overcycle_positive_three}<br>`;
    tooltipContent += `超-3%CT数量:${detailData.overcycle_negative_three}<br>`;
    tooltipContent += `超节拍比例: ${overcycle_ratio.toFixed(2)}%`;

    return tooltipContent;
  }.bind(this),
},
    toolbox: {
      show: true,
      feature: {
        mark: { show: true },
        dataView: { show: true, readOnly: false },
        saveAsImage: { show: true },
      },
    },
        legend: {
          data: ['平均节拍', 'FTQ', '超节拍比例','目标节拍','目标上限+5%','目标下限-5%']
        },
        xAxis: {
          type: 'category',
          data: this.mockdata.map(item => item.station),
          axisLabel: {
            rotate: 45 // 将 x 轴标签倾斜 45 度
          }
        },

dataZoom: [
  {
    type: 'slider', 
    bottom: 10,
    show: true, 
    start: 0, 
    end: 100, 
    handleSize: '80%', 
    height: 20, 
  },
  {
    type: 'inside', 
    show: true, 
    start: 0, 
    end: 100, 
  },
],
        yAxis: [
          {
            type: 'value',
            name: '节拍',
            position: 'left',
            axisLabel: {
              formatter: '{value}'
            }
          },
          {
            type: 'value',
            name: 'Rate (%)',
            position: 'right',
            axisLabel: {
              formatter: '{value} %'
            },
            max: 100,
          }
        ],
        series: [
        {
      name: '平均节拍',
      type: 'bar',
      data: this.mockdata.map(item => item.cycletime),
      yAxisIndex: 0,
      itemStyle: {
          normal: {
            color: function(params) {
              const detailData = filteredData[params.dataIndex]; // 获取当前数据点的详细信息
              if (detailData.isOverCycle) {
                return 'red'; 
              } else if(detailData.islessCycle) {
                return 'orange'; 
              }
              else {
                return '#00ff00';
              }
            }
          }
        },
        },
        {
        name: '目标上限+5%',
        type: 'line',
        step: 'start',
        data: upperLimit,
        symbol: 'circle',
        color: 'red',
        lineStyle: {
          color: 'red',
          width: 1,
          type: 'dashed',
        },
        yAxisIndex: 0,
      },
      {
        name: '目标下限-5%',
        type: 'line',
        step: 'start',
        data: lowerLimit,
        symbol: 'circle',
        color: 'orange',
        lineStyle: {
          color: 'orange',
          width: 1,
          type: 'dashed',
        },
        yAxisIndex: 0,
      },
        {
            name: 'FTQ',
            type: 'line',
            data: this.mockdata.map(item => parseFloat(item.ftq)*100),
            color:'#b6a2de',
            yAxisIndex: 1,
            label: {
    show: false, // 默认不显示标签
  },
  emphasis: { // 鼠标悬停时的高亮状态配置
    label: {
      show: true, // 鼠标悬停时显示标签
      formatter: function(params) {
        return params.value.toFixed(2) + ' %'; // 格式化显示内容
      }
    }
  },
          },
          {
            name: '超节拍比例',
            type: 'line',
            data: this.mockdata.map(item => (item.overcycle / (item.count_good+item.count_reject))*100),
            yAxisIndex: 1,
            color:'#EDAFDA',
            label: {
    show: false, // 默认不显示标签
  },
  emphasis: {
    label: {
      show: true, // 鼠标悬停时显示标签
      formatter: function(params) {
        return params.value.toFixed(2) + ' %'; // 格式化显示内容
      }
    }
  },
          }
        ]
      };
     // 过滤数据

      const targetCycleFiltered = Object.entries(this.targetCycleData)
      .filter(([station]) => !this.stationsToExclude.includes(station))
      .reduce((acc, [station, cycle]) => ({ ...acc, [station]: cycle }), {});

      this.targetCycleData = targetCycleFiltered;
      option.xAxis.data = filteredData.map(item => item.station);
      const validTargetCycles = targetCycleForStations.filter(({ value }) => value !== null && value !== 'N/A');
      console.log("手动:", validTargetCycles.map(item => item.name));

      option.series.push({
    name: '目标节拍',
    type: 'line',
    step: 'start', 
        data: validTargetCycles.map(item => item.value), 
    symbol: 'circle', 
    color:'#00ff00',
    lineStyle: {
      color: '#00ff00', 
      width: 1.4,
      type:'dashed',
    },
    yAxisIndex: 0, 
      });
  
      option.series.forEach((series, index) => {
    switch(index) {
      case 0: 
        series.data = filteredData.map(item => item.cycletime);
        break;
      case 3: 
        series.data = filteredData.map(item => parseFloat(item.ftq)*100);
        break;
      case 4: 
        series.data = filteredData.map(item => {
         const total = item.count_good + item.count_reject;
          return total > 0 ? (item.overcycle / total) * 100 : 0;});
          break;
      case 1:
        series.data = targetCycleForStations.map(item => item.value * 1.05);
        break;
      case 2:
        series.data = targetCycleForStations.map(item => item.value * 0.95)
        break;
    }
  });
      this.chart.setOption(option);
      this.chart.on(
        "click",
        (param) => {
          console.log("Clicked station:", param.name);
    console.log("Query object to be passed:", { station: param.name });
          this.$router.push({
            path: "/Time_slicing",
            query: { station: param.name },
          });
        },
      );
    }
  },
   beforeDestroy() {
    if (this.chart) {
      this.chart.dispose(); 
    }
  },
};
</script>

<style scoped>
.container {
  width: 100%;
  max-width: 1300px;
  margin: 0 auto;
  padding: 20px;
}

.title {
  text-align: center;
  margin-bottom: 30px;
  font-size: 28px;
}

.button-group {
  display: flex;
  justify-content: center;
  margin-top: 20px;
}
/* 基础按钮样式 */
.button {
  background-color: #007bff; /* 默认背景颜色 */
  color: white; /* 文字颜色 */
  border: none; /* 无边框 */
  padding: 10px 20px; /* 内边距 */
  cursor: pointer; /* 鼠标指针为手型 */
  border-radius: 5px; /* 圆角 */
  font-size: 16px; /* 字体大小 */
  transition: background-color 0.3s ease; /* 过渡效果 */
}

.white-button {
  background-color: white; /* 白色背景 */
  color: black; /* 黑色文字以提高对比度 */
  border: 1px solid #ccc; /* 添加浅灰色边框以便区分 */
}

.button:active {
  background-color: #00b327; /* 深色背景 */
  transform: scale(0.8); /* 可选：点击时稍微缩小，增加按钮反馈 */
}

.grid-buttons {
  display: grid;
  grid-template-columns: repeat(10, 1fr); /* 创建三列等宽的网格 */
  gap: 10px; /* 网格单元间的间距 */
}
.reset-adjustments {
  text-align: left; /* Align the button to the left */
}

</style>